package cn.itcast.controller;

import cn.itcast.constant.MessageConstant;
import cn.itcast.interfaces.MemberService;
import cn.itcast.interfaces.ReportService;
import cn.itcast.interfaces.SetmealService;
import cn.itcast.pojo.DateVO;
import cn.itcast.pojo.Result;
import cn.itcast.utils.DateUtils;
import com.alibaba.dubbo.config.annotation.Reference;
import io.reactivex.Observable;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @author: peterChen
 * @date: 2019/8/16 19:22
 * @description: TODO
 * @version: 1.0
 */
@Slf4j
@RestController
@RequestMapping("report")
public class ReportController {

    @Reference
    private MemberService memberService;
    @Reference
    private SetmealService setmealService;
    @Reference
    private ReportService reportService;


    /**
     * 获取当前日期之前12个月份的会员数据
     * @return
     */
    @RequestMapping("/getMemberReport")
    public Result getMemberReport(@RequestBody(required = false) DateVO dateVO) throws Exception {
        List<String> months = new ArrayList<>();
        System.out.println(dateVO);
        if(ObjectUtils.isEmpty(dateVO) ){
            //StringUtils.isEmpty(dateVO.getBeginDate()) && StringUtils.isEmpty(dateVO.getEndDate())
        //创建日期类
        Calendar cal = Calendar.getInstance();
        //切换到当前日期的之前的第12个月
        cal.add(Calendar.MONTH,-12);
        //循环添加12个月的日期（需转换格式yyyy-MM）
        for (int i = 0; i < 12; i++) {
            cal.add(Calendar.MONTH,+1);
            //转换格式
            String month = new SimpleDateFormat("yyyy.MM").format(cal.getTime());
            months.add(month);
            }
        }else {
            //获取查询起始日期
            String beginDate = DateUtils.parseDate2String(dateVO.getBeginDate());
            String endDate = DateUtils.parseDate2String(dateVO.getEndDate());
            List<String> monthList = DateUtils.getMonthBetween(beginDate, endDate, "yyyy.MM");
            if(monthList.size()>=12){
                for (int i = monthList.size()-1;i>0;i--){
                    months.add(months.get(i));
                    if(months.size()>=12){
                        break;
                    }
                }
            }
        }
        //调用service层方法获取截至到对应月份的会员数量
        List<Integer> memberCount = memberService.findMemberCountByMonth(months);
        //添加到map集合中，返回前端
        Map<String, Object> map = new HashMap<>();
        map.put("months",months);
        map.put("memberCount",memberCount);
        return new Result(true, MessageConstant.GET_MEMBER_NUMBER_REPORT_SUCCESS,map);
    }

    /**
     * 获取所有套餐及对应套餐预约数量
     * @return
     */
    @RequestMapping("/getSetmealReport")
    public Result getSetmealReport(){
        //data:{setmealNames:[],setmealCount:[{name:v,count:v}，{}，{}]}
        //
       List<Map<String,Object>> list = setmealService.findSetmealCount();
       Map<String, Object> map = new HashMap<>();
       map.put("setmealCount",list);
       List<String> setmealNames = new ArrayList<>();
        for (Map map1 : list) {
            String setmealName = (String) map1.get("name");
            setmealNames.add(setmealName);
        }
       map.put("setmealNames",setmealNames);
       return new Result(true,MessageConstant.GET_SETMEAL_COUNT_REPORT_SUCCESS,map);
    }

    /**
     * 获取所有运营数据
     * @return
     */
    @RequestMapping("/getBusinessReportData")
    public Result getBusinessReportData(){
        try {
            Map<String,Object> map = reportService.getBusinessReport();
            return new Result(true,MessageConstant.GET_BUSINESS_REPORT_SUCCESS,map);
        } catch (Exception e) {
            //e.printStackTrace();
            log.error("get business report error.",e);
            return new Result(false,MessageConstant.GET_BUSINESS_REPORT_FAIL);
        }
    }

    /**
     * 将运营数据写入到模板表格中并设置导出下载
     * @param request
     * @param response
     * @return
     */
    @RequestMapping("/exportBusinessReport")
    public Result exportBusinessReport(HttpServletRequest request, HttpServletResponse response){
        /**
         * 将获取的的excel表单数据按指定位置写到模板中，并获取输出流写出
         */

        try {
            //获取读取的数据
            Map<String, Object> map = reportService.getBusinessReport();
            //获取所有数据
            String reportDate = (String) map.get("reportDate");
            Integer todayNewMember = (Integer) map.get("todayNewMember");
            Integer totalMember = (Integer) map.get("totalMember");
            Integer thisWeekNewMember = (Integer) map.get("thisWeekNewMember");
            Integer thisMonthNewMember = (Integer) map.get("thisMonthNewMember");
            Integer todayOrderNumber = (Integer) map.get("todayOrderNumber");
            Integer todayVisitsNumber = (Integer) map.get("todayVisitsNumber");
            Integer thisWeekOrderNumber = (Integer) map.get("thisWeekOrderNumber");
            Integer thisWeekVisitsNumber = (Integer) map.get("thisWeekVisitsNumber");
            Integer thisMonthOrderNumber = (Integer) map.get("thisMonthOrderNumber");
            Integer thisMonthVisitsNumber = (Integer) map.get("thisMonthVisitsNumber");
            List<Map<String,Object>> hotSetmeal = (List<Map<String, Object>>) map.get("hotSetmeal");
            //获取模板路径
            String realPath = request.getSession().getServletContext().getRealPath("template"+ File.separator+"report_template.xlsx");
            //创建工作簿对象
            XSSFWorkbook sheets = new XSSFWorkbook(new FileInputStream(realPath));
            //获取表格对象
            XSSFSheet sheet = sheets.getSheetAt(0);
            //填充日期
            sheet.getRow(2).getCell(5).setCellValue(reportDate);
            //填充会员数据统计
            sheet.getRow(4).getCell(5).setCellValue(todayNewMember);  //今日新增会员数
            sheet.getRow(4).getCell(7).setCellValue(totalMember);  //总会员数
            sheet.getRow(5).getCell(5).setCellValue(thisWeekNewMember);  //本周新增会员数
            sheet.getRow(5).getCell(7).setCellValue(thisMonthNewMember);  //本月新增会员数
            //填充预约到诊数据统计
            sheet.getRow(7).getCell(5).setCellValue(todayOrderNumber);  //今日预约数
            sheet.getRow(7).getCell(7).setCellValue(todayVisitsNumber);  //今日到诊数
            sheet.getRow(8).getCell(5).setCellValue(thisWeekOrderNumber);  //本周预约数
            sheet.getRow(8).getCell(7).setCellValue(thisWeekVisitsNumber);  //本周到诊数
            sheet.getRow(9).getCell(5).setCellValue(thisMonthOrderNumber);  //本月预约数
            sheet.getRow(9).getCell(7).setCellValue(thisMonthVisitsNumber);  //本月到诊数
            //循环填充预约热门的套餐
            AtomicReference<Integer> rowNum = new AtomicReference<>(12);
            /*for (Map<String, Object> setmeal : hotSetmeal) {
                String setmealname = (String) setmeal.get("name");  //套餐名称
                long setmeal_count = (long) setmeal.get("setmeal_count");  //套餐数量
                BigDecimal proportion = (BigDecimal) setmeal.get("proportion");  //套餐占比
                //System.out.println(setmealname);
                //System.out.println(setmeal_count);
                //System.out.println(proportion.doubleValue());
                XSSFRow row = sheet.getRow(rowNum++);
                row.getCell(4).setCellValue(setmealname);
                row.getCell(5).setCellValue(setmeal_count);
                row.getCell(6).setCellValue(proportion.doubleValue());
            }*/
            //Rxjava遍历
            Observable.fromIterable(hotSetmeal).subscribe(setmeal->{
                String setmealname = (String) setmeal.get("name");  //套餐名称
                long setmeal_count = (long) setmeal.get("setmeal_count");  //套餐数量
                BigDecimal proportion = (BigDecimal) setmeal.get("proportion");  //套餐占比
                //System.out.println(setmealname);
                //System.out.println(setmeal_count);
                //System.out.println(proportion.doubleValue());
                XSSFRow row = sheet.getRow(rowNum.getAndSet(rowNum.get() + 1));
                row.getCell(4).setCellValue(setmealname);
                row.getCell(5).setCellValue(setmeal_count);
                row.getCell(6).setCellValue(proportion.doubleValue());
            });

            //获取输出流下载
            ServletOutputStream os = response.getOutputStream();
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("content-Disposition","attachment;filename=report.xlsx");
            sheets.write(os);
            os.flush();
            os.close();
            sheets.close();
            return null;


        } catch (Exception e) {
            //e.printStackTrace();
            log.error("report excel error.",e);
            return new Result(false,MessageConstant.GET_BUSINESS_REPORT_FAIL,null);
        }
    }

    @RequestMapping("/getSexReport")
    public Result getSexReport(){
        List<Map<String,Object>> listmap = setmealService.getSexReport();
        Map<String, Object> map = new HashMap<>();
        //ArrayList<Map> maps = new ArrayList<>();
        map.put("sexCount",listmap);
        List<String> sex = new ArrayList<>();
        for (Map map1 : listmap) {
            String sexName = (String) map1.get("name");
            if(sexName == "1"){
                sex.add("1-男");
            }else{
                sex.add("2-女");
            }
        }
        map.put("sexCount",listmap);
        map.put("name",sex);
        return new Result(true,MessageConstant.GET_SETMEAL_COUNT_REPORT_SUCCESS,map);
    }
}
